#include "searchwig.h"
#include "ui_searchwig.h"
#include <QNetworkInterface>


searchwig::searchwig(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::searchwig)
{
    ui->setupUi(this);
    ui->online_button->setStyleSheet("QPushButton {background: transparent;background-color: rgba(255, 255, 255, 50); color:white;}");
    ui->search_button->setStyleSheet("QPushButton {background: transparent;background-color: rgba(255, 255, 255, 50); color:white;}");
    ui->ota_button->setStyleSheet("QPushButton {background: transparent;background-color: rgba(255, 255, 255, 50); color:white;}");
    ui->online_edit->setStyleSheet("QTextEdit {background-color: rgba(255, 255, 255, 50);border: 1px solid rgba(0, 0, 0, 30); color:white;}");
    ui->search_edit->setStyleSheet("QTextEdit {background-color: rgba(255, 255, 255, 50);border: 1px solid rgba(0, 0, 0, 30); color:white;}");
    ui->ota_button->setEnabled(false);
    ui->ota_button->setStyleSheet("background-color: rgba(128, 128, 128, 150);");

    tcpSocket = new QTcpSocket(this);
    udpSocket = new QUdpSocket(this);
    deviceOnline = false;

    connect(udpSocket,&QUdpSocket::readyRead,this,&searchwig::processUdpResponse);    
    connect(tcpSocket, &QTcpSocket::connected, this, &searchwig::onTcpConnected);
    connect(tcpSocket, &QTcpSocket::disconnected, this, &searchwig::onTcpDisconnected);
    connect(tcpSocket, &QTcpSocket::readyRead, this, &searchwig::onTcpReadyRead);
    connect(tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(onTcpError(QAbstractSocket::SocketError)));
}


searchwig::~searchwig()
{
    delete ui;
    if(tcpSocket->isOpen())
    {
        tcpSocket->disconnectFromHost();
    }
    udpSocket->close();
    delete udpSocket;
    delete tcpSocket;
}

//发送udp广播发现设备
void searchwig::sendDiscoveryBroadcast()
{
    // 发送UDP广播
    QByteArray datagram = "DEVICE_DISCOVERY";
    quint16 udpPort = 9999;

    // 获取所有网络接口
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    foreach (const QNetworkInterface &interface, interfaces)
    {
        // 只处理活动的、非回环的、支持广播的接口
        if ((interface.flags() & QNetworkInterface::IsUp)
                &&(interface.flags() & QNetworkInterface::IsRunning)
                &&!(interface.flags() & QNetworkInterface::IsLoopBack)
                &&(interface.flags() & QNetworkInterface::CanBroadcast))
        {

            // 获取接口的所有IP地址
            QList<QNetworkAddressEntry> entries = interface.addressEntries();
            foreach (const QNetworkAddressEntry &entry, entries)
            {
                // 只处理IPv4地址
                if (!entry.broadcast().isNull() && entry.ip().protocol() == QAbstractSocket::IPv4Protocol)
                {
                    // 发送广播
                    udpSocket->writeDatagram(datagram, entry.broadcast(), udpPort);
                    //ui->search_edit->append("发送发现广播到: " + entry.broadcast().toString());
                }
            }
        }
    }

}

//处理udp响应
void searchwig::processUdpResponse()
{
    while (udpSocket->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(udpSocket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

        QString response = QString::fromUtf8(datagram);
        //ui->search_edit->append("收到UDP响应: " + response + " 来自 " + sender.toString() + ":" + QString::number(senderPort));

        // 解析响应
        if (response.startsWith("DEVICE_RESPONSE:"))
        {
            QStringList parts = response.split(":");
            if (parts.size() == 3)
            {
                QString ip = parts[1];
                quint16 port = parts[2].toUShort();

                ui->search_edit->append("发现设备: IP=" + ip + ", 端口=" + QString::number(port));

                emit IpSignal(ip);

                // 连接到TCP服务器
                connectToTcpServer(ip, port);
                return; // 只处理第一个响应
            }
        }
    }
}

//连接tcp
void searchwig::connectToTcpServer(const QString &ip, quint16 port)
{
    if (tcpSocket->state() == QAbstractSocket::ConnectedState)
    {
        tcpSocket->disconnectFromHost();
    }

    tcpSocket->connectToHost(ip, port);
    ui->search_edit->append("正在连接到TCP服务器 " + ip + ":" + QString::number(port));
}


//连接成功
void searchwig::onTcpConnected()
{
    ui->search_edit->append("已连接到TCP服务器");
    ui->ota_button->setEnabled(true);
    ui->ota_button->setStyleSheet("QPushButton {background: transparent;background-color: rgba(255, 255, 255, 50); color:white;}");
}


//断开连接
void searchwig::onTcpDisconnected()
{
    ui->search_edit->append("与TCP服务器断开连接");
    ui->ota_button->setEnabled(false);
    ui->ota_button->setStyleSheet("background-color: rgba(128, 128, 128, 150);");
}


//读取数据
void searchwig::onTcpReadyRead()
{
    QByteArray data = tcpSocket->readAll();

    //ui->online_edit->append(QString::fromUtf8(data));


    QString msg = QString::fromUtf8(data);
    qDebug() << msg << endl;

    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(msg.toUtf8(), &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        qWarning() << "JSON parse error:" << parseError.errorString();
        return;
    }

    if (!doc.isObject()) {
        qWarning() << "JSON is not an object!";
        return;
    }

    QJsonObject obj = doc.object();

    if (obj.contains("ONLINE")) {
        int online = obj["ONLINE"].toInt();
        deviceOnline = (online == 1);
        qDebug() << "Device online status:" << deviceOnline;
    }

}


//tcp错误处理
void searchwig::onTcpError(QAbstractSocket::SocketError error)
{
    ui->search_edit->append("TCP错误: " + tcpSocket->errorString());
    ui->ota_button->setEnabled(false);
    ui->ota_button->setStyleSheet("background-color: rgba(128, 128, 128, 150);");
}


//设备搜索
void searchwig::on_search_button_clicked()
{
    // 先发送UDP广播发现设备
    ui->search_edit->clear();
    ui->search_edit->append("正在搜索设备...");
    sendDiscoveryBroadcast();
}




//在线状态
void searchwig::on_online_button_clicked()
{
    if( deviceOnline == true)
    {
        ui->online_edit->setText("设备在线");
    }
    else
    {
        ui->online_edit->setText("设备不在线");
    }

}


//OTA
void searchwig::on_ota_button_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this, "选择OTA文件", "", "All Files (*)");
    if (!filePath.isEmpty()) {
        sendFile(filePath);
    }
}

// 发送文件
void searchwig::sendFile(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly))
    {
        QMessageBox::warning(this, "错误", "无法打开文件");
        return;
    }

    // 先发送文件名
    QFileInfo fileInfo(filePath);
    QString fileName = fileInfo.fileName();
    tcpSocket->write(fileName.toUtf8());
    tcpSocket->waitForBytesWritten();

    // 然后发送文件内容
    QByteArray fileData = file.readAll();


    if (tcpSocket->write(fileData) == -1)
    {
        QMessageBox::critical(this, "错误", "文件发送失败: " + tcpSocket->errorString());
    }
    else
    {
        QMessageBox::information(this, "成功", QString("文件发送成功！\n文件名: %1\n大小: %2 字节").arg(fileName).arg(fileData.size()));
    }

    file.close();
}
